import configparser
import glob
import os
import shutil
import socket
import threading
import time

from PyQt5.QtCore import pyqtSignal, Qt
from PyQt5.QtGui import QIcon, QTextCursor, QCursor
from fbs_runtime.application_context.PyQt5 import ApplicationContext
from PyQt5.QtWidgets import QMainWindow, QDialog, QMessageBox, QTableWidgetItem, QFileDialog, \
    QListWidgetItem, QMenu, QAction, QStackedWidget
import sys
from ui_main import Ui_mainWindow
from ui_add_job import *
# from ftpOpt import FtpOpt
from utils import asynctask
from ftpclient import FtpClient, FtpLoginInfo

from src.main.python.transferwidget import TransferWidget
from src.main.python.ui_remoteFileDialog import Ui_remoteFileDialog

# joblist = [{'local_dir': 'D:/software-project/ftpsync/src/ui','remote_dir': '/1122'}]
from utils.publicFun import save_obj, load_obj, _async_raise
joblist = []
from settings import BASE_DIR, conf, ENCODING
config_file = conf
# from real_time_sync import real_time_sync, list_dir, refresh_cachehash
from real_time_sync import RealTimeSync
g_realtime_sync = RealTimeSync()
# refresh_cachehash = RealTimeSync.refresh_cachehash
from utils.self_logging import Logger
sys.setrecursionlimit(2000000)
log = Logger('debug.log', level='debug')

class ConnTask(asynctask.TaskAdapter):
    def __init__(self, view, login_info: FtpLoginInfo,client_ftp=None):
        asynctask.TaskAdapter.__init__(self)
        self.view = view
        self.login_info = login_info
        self.res = False
        self.e = None
        self.client_ftp = client_ftp
    def do_in_background(self):
        try:
            self.client_ftp.connect_login(self.login_info)
        except Exception as e:
            self.client_ftp.disconnect()
            self.res = False
            self.e = e
        else:
            self.res = True
            self.e = None

    def on_post_execute(self):
        if self.res:
            self.view.setstate_connect()
            pass
        elif isinstance(self.e, Exception):
            print(self.e)
            # self.view.setstate_disconnect()
            # self.view.status_label.setText(str(self.e))
        # self.view.ui.ConnectButton.setEnabled(True)

class UploadTask(asynctask.TaskAdapter):
    def __init__(self, view, client_ftp=None, configObj=None):
        asynctask.TaskAdapter.__init__(self)
        self.view = view
        self.res = False
        self.e = None
        self.client_ftp = client_ftp
        self.configObj = configObj
    def do_in_background(self):
        try:
            index = self.view.listWidget.currentRow()
            # config = configparser.ConfigParser()
            # config.read(os.path.join(BASE_DIR, conf), encoding=ENCODING)
            # local_dir = config.get('client', 'local_dir')
            # remote_dir = config.get('client', 'remote_dir')
            local_dir = self.configObj['local_dir']
            remote_dir = self.configObj['remote_dir']
            self.client_ftp.upload_dir(local_dir, remote_dir)
            shutil.copytree(local_dir, local_dir.split('/')[0] + r'/ftp__/{}'.format('__备份') + time.strftime('%Y%m%d%H%M%S', time.localtime(time.time())))
            for file_name in os.listdir(local_dir):
                filenames = local_dir + r'/{}'.format(file_name)
                if os.path.isdir(filenames):
                    shutil.rmtree(filenames)
                else:
                    os.remove(filenames)
        except Exception as e:
            print('传输问题', e)
            self.res = False
            self.e = e
        else:
            self.res = True
            self.e = None

    def on_post_execute(self):
        if self.res:
            print('传输完成')
            pass
        elif isinstance(self.e, Exception):
            print(self.e)
        self.view.action_synchronize.setDisabled(False)
class SignalOut:
    def __init__(self, signal):
        self.signal = signal

    def write(self, out):
        self.signal.emit(out)

    def flush(self):
        pass



class MyWindow(QMainWindow, Ui_mainWindow):
    _signal = pyqtSignal(object)
    out_signal = pyqtSignal(object)
    async_signal = pyqtSignal(object)
    _textBrowser_signal = pyqtSignal(object)
    thread = None
    _flag = 'add'
    m_jobStatistic = {}
    def __init__(self, parent=None):
        super(MyWindow, self).__init__(parent)
        self.setupUi(self)
        self.async_task = asynctask.AsyncTask(self.async_signal)
        self.TransferWidget = TransferWidget()
        self.TransferWidget.setObjectName("TransferWidget")
        self.TransferWidget.setColumnCount(5)
        self.actionxinj.triggered.connect(self.slot_invoke_addjob)
        self.action_synchronize.triggered.connect(self.slot_action_sync)
        self._signal.connect(self.mySignal)
        self.out_signal.connect(self.text_edit_out)
        self._textBrowser_signal.connect(self.textBrowser_edit_out)
        sys.stdout = SignalOut(self.out_signal)
        # self.client = FtpClient.ftp()#not use
        # 声明在listWidget创建右键菜单
        self.listWidget.setContextMenuPolicy(Qt.CustomContextMenu)
        self.listWidget.customContextMenuRequested.connect(self.create_rightmenu)  # 连接到菜单显示函数

        config = configparser.ConfigParser()
        config.read(os.path.join(BASE_DIR, conf), encoding=ENCODING)


        sectionNum = 0
        conf_sections = config.sections()
        for sec in conf_sections:
            item = QListWidgetItem()
            jobName = ''
            if '新建任务' in sec:
                jobName = sec
            item.setText(jobName)
            if config.has_section(jobName):
                self.listWidget.addItem(item)
                config.set(jobName, 'is_real_time', '0')
                try:
                    with open(os.path.join(BASE_DIR, conf), 'w', encoding=ENCODING) as tx:
                        config.write(tx)
                    tx.close()
                except:
                    print('更改配置文件失败')

        # while True:
        #     item = QListWidgetItem()
        #     jobName = '新建任务%i' % sectionNum
        #     item.setText(jobName)
        #     if config.has_section(jobName):
        #         self.listWidget.addItem(item)
        #         sectionNum+=1
        #         config.set(jobName, 'is_real_time', '0')
        #         try:
        #             with open(os.path.join(BASE_DIR, conf), 'w', encoding=ENCODING) as tx:
        #                 config.write(tx)
        #             tx.close()
        #         except:
        #             print('更改配置文件失败')
        #     else:
        #         break

        #item = QListWidgetItem()
        # if not self.listWidget.count() > 0:#初始化任务并根据配置文件内容启动实时同步
        #     item.setText('新建任务 %i' % self.listWidget.count())
        #     self.listWidget.addItem(item)
        # local_dir = config.get('client', 'local_dir')
        # remote_dir = config.get('client', 'remote_dir')
        # is_real_time = config.get('client', 'is_real_time')
        # IS_REAL_TIME_SYNC = is_real_time
        # ftp = FtpClient(self._textBrowser_signal).ftp()  # 初始化传信号给ftpclient
        # if is_real_time == "1":
        #     self.thread = threading.Thread(target=real_time_sync,
        #                               args=(local_dir, remote_dir, self._textBrowser_signal))
        #     self.thread.setDaemon(True)
        #     self.thread.start()
        #     icon = QIcon()
        #     icon.addPixmap(QtGui.QPixmap(":/job/icons/image/realTimeSync.png"), QtGui.QIcon.Active, QtGui.QIcon.On)
        #     item = self.listWidget.item(0)
        #     item.setIcon(icon)

    # def changeEvent(self, e):
        # e.ignore()
        # if e.type() == QtCore.QEvent.WindowStateChange:
        #     if self.isMinimized():
        #         print("窗口最小化")
        #         e.ignore()
        #     elif self.isMaximized():
        #         print("窗口最大化")
        #     elif self.isFullScreen():
        #         print("全屏显示")
        #     elif self.isActiveWindow():
        #         print("活动窗口")

    # def closeEvent(self, event):
    #     reply = QtWidgets.QMessageBox(QtWidgets.QMessageBox.Question, self.tr("提示"),
    #                                   self.tr("汝妻子我养之，汝勿虑之。\n 汝特么确定要退出吗？"), QtWidgets.QMessageBox.NoButton, self)
    #     yr_btn = reply.addButton(self.tr("是的我要退出"), QtWidgets.QMessageBox.YesRole)
    #     reply.addButton(self.tr("最小化到托盘"), QtWidgets.QMessageBox.NoRole)
    #     reply.exec_()
    #     if reply.clickedButton() == yr_btn:
    #         event.accept()
    #         QtWidgets.qApp.quit()
    #         # sys.exit(app.exec_())
    #     else:
    #         event.ignore()
    #         #
    #         self.setWindowFlags(QtCore.Qt.SplashScreen | QtCore.Qt.FramelessWindowHint)
    #         self.showMinimized()
    def hideEvent(self, e):
        # e.ignore()
        self.hide()#彻底隐藏包括任务栏

    def create_rightmenu(self):
        # 菜单对象
        self.listWidget_menu = QMenu(self)
        self.rMenuRealTimeSync = QAction(u'实时同步',
                                         self)  # self.actionA = self.contextMenu.addAction(QIcon("images/0.png"),u'|  动作A')
        config = configparser.ConfigParser()
        config.read(os.path.join(BASE_DIR, conf), encoding=ENCODING)
        jobName = self.listWidget.selectedItems()[0].text()
        is_real_time = config.get(jobName, 'is_real_time')

        if is_real_time == '1':
            self.rMenuRealTimeSync.setText('取消实时同步')
        # self.actionA.setShortcut('Ctrl+S')  # 设置快捷键
        self.rMenuEdit = QAction(u'编辑', self)
        self.rMenuDelete = QAction(u'删除', self)
        self.listWidget_menu.addAction(self.rMenuRealTimeSync)  # 把动作A选项添加到菜单
        self.listWidget_menu.addAction(self.rMenuEdit)
        self.listWidget_menu.addAction(self.rMenuDelete)
        self.rMenuEdit.triggered.connect(self.slot_invoke_addjob)
        self.rMenuRealTimeSync.triggered.connect(self.slot_real_time_sync)  # 将动作A触发时连接到槽函数 button
        self.rMenuDelete.triggered.connect(self.slot_invoke_delJob)
        self.listWidget_menu.popup(QCursor.pos())  # 声明当鼠标在listWidget控件上右击时，在鼠标位置显示右键菜单   ,exec_,popup两个都可以，
    def slot_invoke_delJob(self):
        print('delete')
        item = self.listWidget.selectedItems()[0]
        jobName = item.text()
        self.listWidget.takeItem(self.listWidget.currentRow())
        config = configparser.ConfigParser()
        config.read(os.path.join(BASE_DIR, conf), encoding=ENCODING)
        config.remove_section(jobName)
        with open(os.path.join(BASE_DIR, conf), 'w', encoding=ENCODING) as tx:
            config.write(tx)
        tx.close()

    def slot_real_time_sync(self):
        # index = self.listWidget.currentRow()
        config = configparser.ConfigParser()
        config.read(os.path.join(BASE_DIR, conf), encoding=ENCODING)

        icon = QIcon()
        icon.addPixmap(QtGui.QPixmap(":/job/icons/image/realTimeSync.png"), QtGui.QIcon.Active, QtGui.QIcon.On)
        # if index != -1:

        item = self.listWidget.selectedItems()[0]
        jobName = item.text()
        is_real_time = config.get(jobName, 'is_real_time')
        if is_real_time == '0':
            config.set(jobName, 'is_real_time', '1')
            try:
                with open(os.path.join(BASE_DIR, conf), 'w', encoding=ENCODING) as tx:
                    config.write(tx)
                tx.close()
            except:
                print('更改配置文件失败')
            IS_REAL_TIME_SYNC = '1'
            local_dir = config.get(jobName, 'local_dir')
            remote_dir = config.get(jobName, 'remote_dir')
            ftp = FtpClient(self._textBrowser_signal).ftp()#初始化 FtpClient.__ftpsignal
            real_time_upload = RealTimeSync()
            thread = threading.Thread(target=real_time_upload.real_time_sync,
                                      args=(jobName, remote_dir, self._textBrowser_signal))
            thread.setDaemon(True)
            if os.path.exists(local_dir):
                item.setIcon(icon)
                thread.start()
            else:
                print('%s不存在' % local_dir)
                return
        else:
            config.set(jobName, 'is_real_time', '0')
            try:
                with open(os.path.join(BASE_DIR, conf), 'w', encoding=ENCODING) as tx:
                    config.write(tx)
                tx.close()
            except:
                print('更改配置文件失败')
            print('取消同步')
            item.setIcon(QIcon())
            IS_REAL_TIME_SYNC = '0'
            # try:
            #     _async_raise(self.thread.ident, SystemExit)
            # except Exception as e:
            #     print('killThreadId', e)
        # with open(conf, 'w', encoding=ENCODING) as tx:
        #     config.write(tx)
        # tx.close()

        # _async_raise(self.thread.ident, SystemExit)


    def slot_action_sync(self):
        print('手动同步')
        sItems = self.listWidget.selectedItems()
        config = configparser.ConfigParser()
        config.read(os.path.join(BASE_DIR ,conf), encoding=ENCODING)
        # user = config.get('client', 'user')
        # pwd = config.get('client', 'pass')
        # host = config.get('client', 'host')
        # port = config.get('client', 'port')
        jobName = sItems[0].text()
        user = config.get(jobName, 'user')
        pwd = config.get(jobName, 'pass')
        host = config.get(jobName, 'host')
        port = config.get(jobName, 'port')
        local_dir = config.get(jobName, 'local_dir')
        login_info = FtpLoginInfo(host, int(port), user, pwd)
        ftp = FtpClient(self._textBrowser_signal).ftp()
        ftp.connect_login(login_info)
        ldir = g_realtime_sync.list_dir( local_dir)
        _cache_statistics = load_obj("_cache_statistics")
        _cache_statistics["total"] = len(ldir.keys())

        _cache_statistics["succeeded"] = 0
        save_obj(_cache_statistics, "_cache_statistics")#归0
        upload_task = UploadTask(self, ftp, {'user': user, 'pwd': pwd, 'host': host, 'port': port, 'local_dir': local_dir, 'remote_dir': config.get(jobName, 'remote_dir')})
        self.async_task.execute(upload_task)
        self.action_synchronize.setDisabled(True)#点击同步后按钮失效
        save_obj(g_realtime_sync.list_dir( config.get('client', 'local_dir')), "_cache_hash")  # 清空自动文件传输缓存

        print(host + '开始上传')



        # index = self.listWidget.currentRow()


    def slot_invoke_addjob(self):
        selectName = None
        print('actionName', self.sender().objectName())
        flag = self.sender().objectName()
        if flag == 'actionxinj':
            self._flag = 'add'
        else:
            self._flag = 'edit'
        if len(self.listWidget.selectedItems()) > 0:
            selectName = self.listWidget.selectedItems()[0].text()
        addjob = AddJob(parent=self._signal, selectName=selectName)
        addjob.exec()
    def ddd(self):
        print(conf)
    def mySignal(self, obj):
        # print('子窗口参数', obj)
        item = QListWidgetItem()
        # icon = QIcon()
        # icon.addPixmap(QtGui.QPixmap(":/job/addFile.png"), QtGui.QIcon.Active, QtGui.QIcon.On)
        # item.setIcon(icon)
        config = configparser.ConfigParser()
        config.read(os.path.join(BASE_DIR, config_file), encoding=ENCODING)
        conf_sections = config.sections()
        for sec in conf_sections:
            item = QListWidgetItem()
            if '新建任务' in sec:
                self.secNum = sec.replace('新建任务', '')
        jobName = '新建任务%i' % (int(self.secNum)+1)  # self.listWidget.count()
        if self._flag == 'edit':  # 编辑/修改
            jobName = obj['selectName']
        else:  # 添加
            if not self.listWidget.count() < 0:
                item.setText(jobName)
                self.listWidget.addItem(item)
        joblist.clear()
        joblist.append(obj)

        try:
            config = configparser.ConfigParser()
            print('update config', obj['local_dir'])
            config.read(os.path.join(BASE_DIR, config_file), encoding=ENCODING)
            # print(str(obj['local_dir']).encode(encoding=ENCODING))#encode是二进制
            try:
                config.add_section(jobName)
            except Exception as e:
                print('addJob', e)
            config.set(jobName, 'user', str(obj['user']))
            config.set(jobName, 'pass', str(obj['pwd']))
            config.set(jobName, 'host', obj['host'])
            config.set(jobName, 'port', obj['port'])
            config.set(jobName, 'local_dir', str(obj['local_dir']))
            config.set(jobName, 'remote_dir', str(obj['remote_dir']))
            config.set(jobName, 'is_real_time', str(0))
            config.set(jobName, 'is_compress_img', str(0))
            if (obj['is_compress_img']):
                config.set(jobName, 'is_compress_img', str(1))
            with open(config_file, 'w', encoding=ENCODING) as conf:
                config.write(conf)
                conf.close()
            # refresh_cachehash()
            ldir = g_realtime_sync.list_dir(str(obj['local_dir']))
            save_obj(ldir, "_cache_hash")#清空存储的文件key
            save_obj({"total": len(ldir), "succeeded": 0, "failed": 0}, jobName+"_cache_statistics")
            self._textBrowser_signal.emit(jobName)
            # path_file_number = glob.glob(pathname=str(obj['local_dir'])+'/*.*')
            # print('文件个数', len(path_file_number))

        except Exception as e:
            QMessageBox.information(self, "错误", str(e))
        # self.refresh()#刷新窗口

    def connect(self, host, port, user, pwd):
        login_info = FtpLoginInfo(host, int(port), user, pwd)
        conn_task = ConnTask(self, login_info,self.client)
        self.async_task.execute(conn_task)
    def text_edit_out(self, out):
        self.textEdit.moveCursor(QTextCursor.End)
        if 'timed out' in str(out):
            self.textEdit.append("<font color=\"#FF0000\">%s</font> " % str(out))
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            config = configparser.ConfigParser()
            config.read(os.path.join(BASE_DIR, conf), encoding=ENCODING)
            tcp_address = config.get('tcp_disconnect', 'tcp_address')
            tcp_port = config.get('tcp_disconnect', 'tcp_port')
            try:
                s.connect((tcp_address, int(tcp_port)))
                keepclass = "连接问题:中断或超时"
                s.send(bytes(keepclass, ENCODING))  # 向服务端发送消息
            except:
                print('tcp连接超时')
        elif '不存在,取消同步' in str(out):
            self.textEdit.append(str(out))
            self.slot_real_time_sync()
        else:
            self.textEdit.insertPlainText(str(out))
        if 'rror' in str(out):
            Logger('error.log', level='error').logger.error(str(out))
        else:
            log.logger.debug(str(out))

    def textBrowser_edit_out(self, jobName=""):

        _cache_statistics = load_obj(jobName+"_cache_statistics")
        text = "共有 " + str(_cache_statistics["total"]) + ", 成功上传 " + str(_cache_statistics["succeeded"])
        self.m_jobStatistic[jobName] = text
        self.textBrowser.clear()
        for key in self.m_jobStatistic:
            textjoin = key + self.m_jobStatistic[key]
            self.textBrowser.append(textjoin)


class RemoteFileDialog(QDialog, Ui_remoteFileDialog):
    def __init__(self, parent=None):
        self._parent = parent
        super(RemoteFileDialog, self).__init__()
        self.setupUi(self)
        host = self._parent.ipAddress.text()
        port = self._parent.port.text()
        user = self._parent.username.text()
        pwd = self._parent.password.text()
        ftp = FtpClient.ftp()
        self._ftp = ftp
        login_info = FtpLoginInfo(host,int(port),user,pwd)
        ftp.connect_login(login_info)

        dir_res = []
        # ftp.dir('/', dir_res.append)
        # dirs = [{'dir_name':f.split(None, 8)[-1],'datetime': f.split(None, 8)[0]+" "+f.split(None, 8)[1]} for f in dir_res if '<DIR>' in f]
        # print (dirs)

        dirs = ftp.dirs()
        self.reShowDirs(dirs)
        self.tableWidget.doubleClicked.connect(self.tableWidget_double_clicked)
        self.buttonBox.accepted.connect(self.accepted)
    def accepted(self):
        self._parent.remote_dir.setText(self.lineEdit.text())
    def reShowDirs(self,dirs):
        count = self.tableWidget.rowCount()
        for indix in range(0, count):
            self.tableWidget.removeRow(0)
        for i in range(0, len(dirs)):
            self.tableWidget.insertRow(i)
            self.tableWidget.setItem(i, 0, QTableWidgetItem(dirs[i]['dir_name']))
            # self.tableWidget.setItem(i, 1, QTableWidgetItem(dirs[i]['datetime']))
        self.tableWidget.insertRow(0)
        self.tableWidget.setItem(0, 0, QTableWidgetItem('上一级'))
        self.tableWidget.setSpan(0, 0, 1, 3)
        self.tableWidget.viewport().update()
    def tableWidget_double_clicked(self, index):
        table_column = index.column()
        table_row = index.row()
        # if table_row == 0:

        current_item = self.tableWidget.item(table_row, 0)
        if table_row == 0 and self.lineEdit.text() != '/':
            a = self.lineEdit.text()
            newLineText = a.replace(a[a.rfind('/'):],'')
            if newLineText == '':
                newLineText = '/'
            self.lineEdit.setText(newLineText)
            dirs = self._ftp.dirs(newLineText)
            self.reShowDirs(dirs)
        elif table_row == 0 and self.lineEdit.text() == '/':
            pass
        else:
            text = ''
            if self.lineEdit.text() != '/':
                text = self.lineEdit.text()
            text = text + '/' + current_item.text()
            self.lineEdit.setText(text)
            self.reShowDirs(self._ftp.dirs(text))


class AddJob(QDialog, Ui_job_create):
    async_signal = pyqtSignal(object)
    out_signal = pyqtSignal(object)

    def __init__(self, parent=None, selectName=None):
        self._parent_signal = parent
        self._selectName = selectName
        super(AddJob, self).__init__()
        self.async_task = asynctask.AsyncTask(self.async_signal)
        self.setupUi(self)
        self.TransferWidget = TransferWidget()
        self.TransferWidget.setObjectName("TransferWidget")
        self.TransferWidget.setColumnCount(5)
        # self.sync_dir_list.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)#列宽自适应
        self.test_connect.clicked.connect(self.slot_testConnect)
        self.add_dir.clicked.connect(self.addTable)
        self.localDirButton.clicked.connect(self.showFileDialog)
        self.remoteDirButton.clicked.connect(self.showRemoteFileDialog)
        self.buttonBox.accepted.connect(self.slot_accept)
        config = configparser.ConfigParser()
        config.read(os.path.join(BASE_DIR, conf), encoding=ENCODING)
        user = config.get('client', 'user')
        pwd = config.get('client', 'pass')
        host = config.get('client', 'host')
        port = config.get('client', 'port')
        local_dir = config.get('client', 'local_dir')
        remote_dir = config.get('client', 'remote_dir')
        if selectName:
            user = config.get(selectName, 'user')
            pwd = config.get(selectName, 'pass')
            host = config.get(selectName, 'host')
            port = config.get(selectName, 'port')
            local_dir = config.get(selectName, 'local_dir')
            remote_dir = config.get(selectName, 'remote_dir')
        self.ipAddress.setText(host)
        self.port.setText(port)
        self.username.setText(user)
        self.password.setText(pwd)
        self.local_dir.setText(local_dir)
        self.remote_dir.setText(remote_dir)
        self.sync_dir_list.hide()  # 暂时不用
        self.horizontalLayoutWidget.hide()# 暂时不用
    def showRemoteFileDialog(self):
        remoteDialog = RemoteFileDialog(self)

        # dir_res = []
        # ftp.dir('/', dir_res.append)
        # # files = [f.split(None, 8)[-1] for f in dir_res if f.startswith('-')]
        # dirs = [{'dir_name': f.split(None, 8)[-1], 'datetime': f.split(None, 8)[0] + " " + f.split(None, 8)[1]} for f in
        #         dir_res if '<DIR>' in f]
        #
        # tablecount = len(dirs)
        # remoteDialog.tableWidget.insertRow(tablecount)
        # for item in dirs:
        #     remoteDialog.tableWidget.setItem(tablecount, 0, QTableWidgetItem(item['dir_name']))
        #     remoteDialog.tableWidget.setItem(tablecount, 1, QTableWidgetItem(item['datetime']))
        #     remoteDialog.tableWidget.setItem(tablecount, 2, QTableWidgetItem(item['datetime']))
        # remoteDialog.tableWidget.viewport().update()
        remoteDialog.exec()

    def slot_accept(self):
        if self.username.text() == '' or self.password.text() == '':
            QMessageBox.information(self, "提示", "输入用户名或者密码不能为空！")
            return
        self._parent_signal.emit({'local_dir': self.local_dir.text(),
                                  'remote_dir': self.remote_dir.text(),
                                  'host': self.ipAddress.text(),'port': self.port.text(),
                                  'user': self.username.text(),'pwd': self.password.text(),
                                  'selectName': self._selectName,
                                  'is_compress_img': self.compress_img.isChecked()
                                  })
        # print('ok')

    def slot_testConnect(self):
        if self.ftp_upload.isChecked():
            print('上传')
            host = self.ipAddress.text()
            port = self.port.text()
            user = self.username.text()
            pwd = self.password.text()
            self.connect(host,port,user,pwd)
            self.test_connect.setText('正在连接')

        elif self.ftp_download.isChecked():
            print('下载')
        else:
            print('同步')
    def connect(self,host,port,user,pwd):#添加任务弹窗测试连接
        login_info = FtpLoginInfo(host, int(port), user, pwd)
        conn_task = ConnTask(self, login_info,FtpClient.ftp())
        self.async_task.execute(conn_task)
    def setstate_connect(self):
        QMessageBox.about(self, "提示", "连接成功!")
        self.test_connect.setText('开始测试')
    def showFileDialog(self):
        localdir = QFileDialog.getExistingDirectory(None, "请选择文件夹路径", "D:\\")
        self.local_dir.setText(localdir)
        # self.local_dir.setText('D:/software-project/ftpsync/src/ui')
        # self.remote_dir.setText('/1122')
    def addTable(self):
        tablecount = int(self.sync_dir_list.rowCount())
        self.sync_dir_list.insertRow(tablecount)
        self.sync_dir_list.setItem(tablecount, 0,QTableWidgetItem(self.local_dir.text()))
        self.sync_dir_list.setItem(tablecount, 1, QTableWidgetItem(self.remote_dir.text()))
        self.sync_dir_list.viewport().update()


class TrayIcon(QtWidgets.QSystemTrayIcon):
    def __init__(self, MainWindow, parent=None):
        super(TrayIcon, self).__init__(parent)
        self.ui = MainWindow
        self.createMenu()

    def createMenu(self):
        self.menu = QtWidgets.QMenu()
        self.showAction1 = QtWidgets.QAction("打开", self, triggered=self.show_window)
        # self.showAction2 = QtWidgets.QAction("显示通知", self, triggered=self.showMsg)
        self.quitAction = QtWidgets.QAction("退出", self, triggered=self.quit)

        self.menu.addAction(self.showAction1)
        # self.menu.addAction(self.showAction2)
        self.menu.addAction(self.quitAction)
        self.setContextMenu(self.menu)

        # 设置图标
        self.setIcon(QtGui.QIcon(":/job/icons/base/16.png"))
        self.icon = self.MessageIcon()

        # 把鼠标点击图标的信号和槽连接
        self.activated.connect(self.onIconClicked)

    def showMsg(self):
        self.showMessage("Message", "skr at here", self.icon)

    def show_window(self):
        # 若是最小化，则先正常显示窗口，再变为活动窗口（暂时显示在最前面）
        self.ui.showNormal()
        self.ui.activateWindow()

    def quit(self):
        QtWidgets.qApp.quit()

    # 鼠标点击icon传递的信号会带有一个整形的值，1是表示单击右键，2是双击，3是单击左键，4是用鼠标中键点击
    def onIconClicked(self, reason):
        if reason == 2 or reason == 3:
            # self.showMessage("Message", "skr at here", self.icon)
            if self.ui.isMinimized() or not self.ui.isVisible():
                # 若是最小化，则先正常显示窗口，再变为活动窗口（暂时显示在最前面）
                self.ui.showNormal()
                self.ui.activateWindow()

                self.ui.show()
            else:
                # 若不是最小化，则最小化
                self.ui.showMinimized()

                self.ui.show()


if __name__ == '__main__':
    appctxt = ApplicationContext()       # 1. Instantiate ApplicationContext
    # window = QMainWindow()
    window = MyWindow()
    # window.resize(250, 150)

    window.show()
    ti = TrayIcon(window)
    ti.show()
    exit_code = appctxt.app.exec_()      # 2. Invoke appctxt.app.exec_()
    sys.exit(exit_code)
